package au.com.langdale.gwt.client.model;

import com.google.gwt.user.client.rpc.IsSerializable;

/**
 * A Property enables access to an object in situations where its
 * type is not known at compile time and no java reflection is available
 * at runtime. This is the situation in some GWT user interface code.<p>
 * 
 * This class is the base of all Properties and specifies their requirements:
 * 
 * - A Property provides general accessors to set and get the property value,
 * given a model object.<p>
 * 
 * - A Property provides basic metadata, the name and the length of the 
 * string representation.  (Numeric properties also provide precision
 * and scale - see IntegerProperty.)<p>
 * 
 * - A Property may also provide validation.<p>
 * 
 * A concrete Property defines,accessors, metadata and validation for one
 * property of a class.  It must be passed an instance of that class
 * for the accessors or validation to be applied.<p>  
 * 
 * As a Property does not contain or wrap the instance, the metadata 
 * can be used when no instance is available.  The Property is usually
 * a stateless singleton.<p> 
 * 
 * Specialisations of Property are defined for some basic data types,
 * such as StringProperty and IntegerProperty.  These can be subclassed 
 * by concrete properties of the corresponding type.<p>
 * 
 * A set of hibernate templates is provided that generate concrete
 * Property classes, and a singleton instance of each, for database 
 * fields.<p> 
 * 
 * @author adv
 *
 */
public abstract class Property implements IsSerializable {
	
	// access
	public abstract String get(Object model);
	public abstract void set(Object model, String value);
	public abstract boolean isSet(Object model);
	public abstract void set(Object model, boolean value);

	// metadata
	public abstract int getLength();
	public abstract String getName();
	public abstract String getStyleName();
	
	public Property() {
		// make it serializable
	}
	
	public String toString() {
		return getName();
	}
	public String getFieldName() {
		return getName().substring(0, 1).toLowerCase() + getName().substring(1);
	}
	public String validate(Object model) {
		return null;
	}
	
}
